package DataStructures.LinearList;

public class ArrayList<E> extends AbstractList<E> { //继承后，按住ctrl+O,重写父类方法
    //先定义一个object类型的底层数组，用Object接收，因为泛型顶层是Object，Object类型又能存很多东西
    Object[] arr = new Object[1];

    private int size = 0;  //初始size长度设置为0

    @Override
    public int size() {
        return size;  //要获取的是数组有多少个元素，而不是数组长度
    }

    @Override
    public void add(E e, int index) {
        //判断插入位置是否合法
        if(index > size) throw new IllegalArgumentException("非法插入位置");

        //先判断数组是否需要扩容
        if(size >= arr.length){
            Object[] tmparr = new Object[this.arr.length + 10]; //每次扩容10
            //使用for循环实现把arr的元素搬到tmparr，系统提示替换为System.arraycopy()效率更高，这里我们先不用系统的
            for (int i = 0; i < this.arr.length; i++) tmparr[i] = this.arr[i];
            this.arr = tmparr; //把arr成员变量替换为我们创建的临时的tmparr
        }

        //添加元素，把后面的元素往后移动
        int i = size - 1; //定义一个下标i，最后一个元素的下标就是size-1
        while(i >= index){  //判断遍历下标是否达到要插入的index索引位置
            arr[i+1] = arr[i]; //把每个元素往后搬
            i--; //每个元素都要搬，用i来遍历
        }
        arr[index] = e;  //把要插入的元素放到index位置
        size++; //size+1

    }

    @Override
    public E remove(int index) {
        //判断移除位置是否合法
        if(index > size-1) throw new IllegalArgumentException("非法删除位置"); //索引号码比size小1，所以index比较的是size-1

        int i = index;
        E e = (E) arr[index]; //因为返回的是E类型，必须用E类型先存一下值，强制转换一下
        while (i < size-1) {  //最后一个下标的值等于size-1
            arr[i]= arr[i+1];
            i++;
        }
        size--; //记得把size-1
        return e;  //或者直接在这里类型转换也行，不用上次用E接收了
    }

    @Override
    public E get(int index) {
        //还是要判断索引是否大于size
        if(index >= size) throw new IndexOutOfBoundsException("获取位置非法，无法访问指定的下标");
        return (E) arr[index];  //还是要类型转换
    }
}
